package com.ywy.config;

import com.ywy.shiro.AccountRealm;
import com.ywy.shiro.AuthFilter;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shiro配置
 *
 * @author ywy
 * @date 2021/12/27 15:02
 */
@Configuration
public class ShiroConfig {
    @Bean
    public SecurityManager securityManager(AccountRealm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        SecurityUtils.setSecurityManager(securityManager);
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        filterFactoryBean.setSecurityManager(securityManager);
        // 配置登录的url和登录成功的url
        filterFactoryBean.setLoginUrl("/login");
        filterFactoryBean.setSuccessUrl("/user/index");
        // 配置未授权跳转页面
        filterFactoryBean.setUnauthorizedUrl("/error/403");

        // 配置默认过滤器
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("auth", authFilter());
        filterFactoryBean.setFilters(filterMap);

        // 配置拦截规则
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/res/**", "anon");
        filterChainDefinitionMap.put("/captcha.jpg", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/error/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/register", "anon");
        filterChainDefinitionMap.put("/chat/**", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/admin/**", "auth, roles[admin]");
        filterChainDefinitionMap.put("/**", "auth");
        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return filterFactoryBean;
    }

    @Bean
    public AuthFilter authFilter() {
        return new AuthFilter();
    }

    /**
     * 取消SpringBoot自动注册自定义Filter，防止在ShiroFilter之前进入自定义Filter
     * 也可以在配置Filter时filterFactoryBean.setFilters() 直接new出自定义Filter
     * @param filter
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(AuthFilter filter) {
        FilterRegistrationBean registration = new FilterRegistrationBean(filter);
        // 取消Filter的自动注册
        registration.setEnabled(false);
        registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR);
        registration.addUrlPatterns("/*");
        return registration;
    }
}
